package com.scpii.json.rpc;

import java.util.UUID;

import com.scpii.json.JSONException;
import com.scpii.json.JSONUtil;
import com.scpii.json.rpc.JSONRPCParams.Versions;

public abstract class JSONRPCClient {

	protected Versions version;

	protected String encoding = "UTF-8";

	public static JSONRPCClient create(String uri, Versions version) {
		JSONRPCClient client = new JSONRPCHttpClient(uri);
		client.version = version;
		return client;
	}

	protected boolean _debug = false;

	public void setDebug(boolean _debug) {
		this._debug = _debug;
	}

	public boolean isDebug() {
		return _debug;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}

	public void delEncoding() {
		this.encoding = "";
	}

	protected abstract JSONRPCResponse doJSONRequest(String jsonRequest)
			throws JSONRPCException;

	protected JSONRPCResponse doRequest(String method, Object... params)
			throws JSONRPCException {

		String jsonRequestStr = null;

		JSONRPCRequest jsonRequest = new JSONRPCRequest();
		try {
			jsonRequest.setId(UUID.randomUUID().hashCode());
			jsonRequest.setMethod(method);
			jsonRequest.setParams(params);
			jsonRequestStr = JSONUtil.serialize(jsonRequest);
		} catch (JSONException e1) {
			throw new JSONRPCException("Invalid JSON request", e1);
		}
		return doJSONRequest(jsonRequestStr);
	}

	protected int soTimeout = 0, connectionTimeout = 0;

	public int getSoTimeout() {
		return soTimeout;
	}

	public void setSoTimeout(int soTimeout) {
		this.soTimeout = soTimeout;
	}

	public int getConnectionTimeout() {
		return connectionTimeout;
	}

	public void setConnectionTimeout(int connectionTimeout) {
		this.connectionTimeout = connectionTimeout;
	}

	public Object call(String method, Object... params) throws JSONRPCException {
		return doRequest(method, params).getResult();
	}

	public String callString(String method, Object... params)
			throws JSONRPCException {
		Object obj = doRequest(method, params).getResult();
		try {
			if (obj != null) {
				return (String) obj;
			}
		} catch (ClassCastException e) {
			throw new JSONRPCException("could't cast result", e);
		}
		return null;
	}

	public Boolean callBoolean(String method, Object... params)
			throws JSONRPCException {
		Object obj = doRequest(method, params).getResult();
		try {
			if (obj != null) {
				return (Boolean) obj;
			}
		} catch (ClassCastException e) {
			throw new JSONRPCException("could't cast result", e);
		}
		return null;
	}
}
